use crate::entity::cms_article;
use crate::entity::cms_topic;
use crate::utils::current_datetime;
use ane_macros::model_delete;
use ane_macros::model_fetch;
use ane_macros::model_list;
use ane_macros::model_struct;

use sea_orm::prelude::Expr;
use sea_orm::{
    ActiveModelTrait, ColumnTrait, DbConn, DerivePartialModel, EntityTrait, FromQueryResult,
    ModelTrait, PaginatorTrait, PartialModelTrait, QueryFilter, QueryOrder, QueryTrait, Set,
};
use serde::Deserialize;
use validator::Validate;

model_struct!(
    #model=cms_article
    #[derive(Debug, Clone, Deserialize, Validate)]
    pub struct ArticleDo {
        pub topic_id: i32,
        #[validate(length(min = 2, max = 256), non_control_character)]
        pub title: String,
        pub author: String,
        pub fromurl: String,
        pub image: String,
        pub keywords: String,
        pub description: String,
        pub allow_comments: bool,
        pub content: String,
    }
);

model_struct!(
    #model=cms_topic
    #[derive(Debug, Clone, Deserialize, Validate)]
    pub struct TopicDo {
        /// 名称
        #[validate(length(min = 2, max = 32), non_control_character)]
        pub name: String,
        /// 描述
        pub description: String,
        /// 图片
        pub image: String,
        /// 图标
        pub icon: String,
        /// 别名
        pub alias: String,
        /// 排序
        pub order: i16
    }
);

/// cms的管里接口
pub struct Manager;

/// 文章相关的操作
#[allow(unused)]
impl Manager {
    model_list!(
        #model=cms_article
        /// 列出用户的文章列表
        /// # Params
        /// - user_id 用户id
        /// - title 可选，搜索相似的标题
        /// - topic_id 可选，专题的id
        pub fn list_article(
            UserId.eq(user_id:i32),
            Title.contains(title: Option<String>),
            TopicId.eq(topic_id:Option<i32>),
        )
    );

    model_fetch!(
        #model=cms_article
        /// 获得用户的一篇文章
        pub fn fetct_article(UserId.eq(user_id:i32), Id.eq(id:i32))
    );

    pub async fn create_article<AM: Into<cms_article::ActiveModel>>(
        conn: &DbConn,
        user_id: i32,
        data: AM,
    ) -> super::Result<cms_article::Model> {
        let mut model: cms_article::ActiveModel = data.into();
        model.created_at = Set(current_datetime());
        model.updated_at = Set(current_datetime());
        model.user_id = Set(user_id);
        model.status = Set(0);
        model.read_number = Set(0);
        model.insert(conn).await
    }

    pub async fn update_article<AM: Into<cms_article::ActiveModel>>(
        conn: &DbConn,
        user_id: i32,
        id: i32,
        data: AM,
    ) -> super::Result<cms_article::Model> {
        let mut model: cms_article::ActiveModel = data.into();
        model.updated_at = Set(current_datetime());
        model.id = Set(id);
        cms_article::Entity::update(model)
            .filter(cms_article::Column::UserId.eq(user_id))
            .exec(conn)
            .await
    }

    model_delete!(
        #model=cms_article
        /// 删用户的一片文章
        pub fn del_article(UserId.eq(user_id:i32), Id.eq(id:i32))
    );
}

/// 专题相关的操作
#[allow(unused)]
impl Manager {
    model_list!(
        #model=cms_topic
        /// 列出用户的专题
        pub fn list_topic(UserId.eq(user_id:i32))
    );

    model_fetch!(
        #model=cms_topic
        /// 获得用户的一个专题
        pub fn fetct_topic(UserId.eq(user_id:i32), Id.eq(id:i32))
    );

    /// 创建一个专题
    pub async fn create_topic(
        conn: &DbConn,
        user_id: i32,
        data: TopicDo,
    ) -> super::Result<cms_topic::Model> {
        let mut model: cms_topic::ActiveModel = data.into();
        model.created_at = Set(current_datetime());
        model.updated_at = Set(current_datetime());
        model.user_id = Set(user_id);
        model.insert(conn).await
    }

    /// 更新一个专题
    pub async fn update_topic(
        conn: &DbConn,
        user_id: i32,
        id: i32,
        data: TopicDo,
    ) -> super::Result<cms_topic::Model> {
        let mut model: cms_topic::ActiveModel = data.into();
        model.updated_at = Set(current_datetime());
        model.id = Set(id);
        cms_topic::Entity::update(model)
            .filter(cms_topic::Column::UserId.eq(user_id))
            .exec(conn)
            .await
    }

    /// 删除一个专题
    pub async fn del_topic(conn: &DbConn, user_id: i32, id: i32) -> super::Result<()> {
        let s = cms_topic::Entity::delete_many()
            .filter(cms_topic::Column::Id.eq(id))
            .filter(cms_topic::Column::UserId.eq(user_id))
            .exec(conn)
            .await?;
        cms_article::Entity::update_many()
            .col_expr(cms_article::Column::TopicId, Expr::value(0))
            .filter(cms_article::Column::Id.eq(id))
            .filter(cms_article::Column::UserId.eq(user_id))
            .exec(conn);
        Ok(())
    }
}
